package ext;

import ext.load.DataGeom;
import ext.trace.kernel.KernelSqCosine;
import ext.trace.scene.AAGrid;
import ext.trace.scene.Scene;
import ext.trace.scene.SceneNSq;
import image.Image3;
import image.ImageGroup;
import image.disk.FormatPNG;
import image.synth.Synthesizer;
import math.vec2i;
import math.vec3;

/*

UNFINISHED TASKS:
    
    Write an OBJ loader that converts faces to Tri3 objects. 
    
    Derive an intersection routine for Cone3.
    
    Debug the Cylinder3 intersection routine. 
    
    Define AABB3 to be a volume and a surface and derive an intersection routine.
    
    Abstract out the BRDFs from the lighting integrator. 
    
    Merge BRDF implementations with the Material class. -- Have Lambertian extend Material, implement BRDF.
        Make Material an abstract class.
        Make BRDF an interface.
    
    Write a better tonemapping shader that uses set black/grey/white points and clips anything else.
    
    Debug AAGrid to completion.
    
    Extend MATH.matrix to contain transforms, normalization, and the Gram-Schmidt process.
    
*/

public class Program
{
    
    public static void main(String[] args)
    {
        vec2i start = new vec2i(0);
        vec2i size =  new vec2i(540);
        
        ImageGroup target = new ImageGroup(2);
        target.attach(0, new Image3(size));
        target.attach(1, new Image3(size));
        
        Synthesizer synth = new Synthesizer();
        synth.rTarget = target;
        synth.mSeed = 0L;
        synth.mTileSize.set(32);
        
        Scene scene = new SceneNSq();
//        Scene scene = new AAGrid(new vec3(-9), new vec3(9));
        DataGeom.load0(scene);
        
        int output = 0;
        
        PSRT psrt = new PSRT();
        psrt.mColorBgnd = new vec3(0.054902, 0.607843, 0.862745);
        psrt.mRouletteProb = 0.02;
        psrt.mDirectProb = 0.5;
        psrt.mSPP = 32;
        psrt.rScene = scene;
        psrt.rKernel = new KernelSqCosine();
        psrt.mTargetI3 = output;
        synth.computeImage(psrt, start, size);
        System.out.println("PSRT finished.");
        
        Image3.mapAll(target.image3(output), 0.0, 16.0);
        
        PSTonemap pstone = new PSTonemap();
        pstone.mTargetI3 = output;
        synth.computeImage(pstone, start, size);
        System.out.println("PSTonemap finished.");
        
        Image3.mapAll(target.image3(output), 0.0, 1.0);
        
        Image3.flipAroundHoriz(target.image3(output));
        Image3.clampAll(target.image3(output), 0.0, 1.0);
        FormatPNG.save(target.image3(output), "OUTPUT");
    }
    
}